package com.corechina.apex_osswords.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.corechina.apex_osswords.common.*;
import com.corechina.apex_osswords.common.config.WeiXinConfig;
import com.corechina.apex_osswords.domain.dao.CoreMaintenanceEngineerMapper;
import com.corechina.apex_osswords.domain.dao.CoreRemindPlanMapper;
import com.corechina.apex_osswords.domain.dao.CoreUserBindingMapper;
import com.corechina.apex_osswords.domain.dao.CoreWorkOrderMapper;
import com.corechina.apex_osswords.domain.dto.CoreWorkOrderDto;
import com.corechina.apex_osswords.domain.dto.CoreWorkOrderListDto;
import com.corechina.apex_osswords.domain.entity.CoreMaintenanceEngineer;
import com.corechina.apex_osswords.domain.entity.CoreUserBinding;
import com.corechina.apex_osswords.domain.entity.CoreWorkOrder;
import com.corechina.apex_osswords.domain.vo.CoreWorkOrderVo;
import com.corechina.apex_osswords.service.ICoreProjectService;
import com.corechina.apex_osswords.service.ICoreWorkOrderService;
import com.corechina.apex_osswords.service.IRedisService;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 工单表 服务实现类
 * </p>
 *
 * @author cc
 * @since 2022-03-11
 */
@Service
public class CoreWorkOrderServiceImpl extends ServiceImpl<CoreWorkOrderMapper, CoreWorkOrder> implements ICoreWorkOrderService {

    @Autowired
    private CoreWorkOrderMapper coreWorkOrderMapper;

    @Autowired
    private CoreRemindPlanMapper coreRemindPlanMapper;

    @Autowired
    private CoreMaintenanceEngineerMapper coreMaintenanceEngineerMapper;

    @Autowired
    private IRedisService iRedisService;

    @Autowired
    private CoreUserBindingMapper coreUserBindingMapper;

    @Autowired
    private ICoreProjectService iCoreProjectService;

    @Override
    public Response add(CoreWorkOrderDto coreWorkOrderDto) {
        CoreWorkOrder coreWorkOrder = new CoreWorkOrder();
        BeanUtils.copyProperties(coreWorkOrderDto, coreWorkOrder);
        coreWorkOrder.setCreateUserType(0);
        coreWorkOrder.setCreateTime(LocalDateTime.now());
        coreWorkOrder.setState(1);
        coreWorkOrder.setCreator(ShiroUtils.getUserId());
        coreWorkOrder.setOrderNo(this.getOrderNo());
        coreWorkOrder.setAuditor(coreWorkOrderDto.getRepairId());
        coreWorkOrder.setEnterpriseId(iCoreProjectService.getById(coreWorkOrderDto.getProjectId()).getEnterpriseId());
        coreWorkOrderMapper.insert(coreWorkOrder);

        //提醒计划暂时不需要
/*        if (coreWorkOrderDto.getRemindPlanType() != null && !coreWorkOrderDto.getRemindPlanType().equals(0) && coreWorkOrderDto.getCoreRemindPlanList() != null) {
            for (CoreRemindPlan coreRemindPlan : coreWorkOrderDto.getCoreRemindPlanList()) {
                coreRemindPlan.setWorkOrderId(coreWorkOrder.getId());
                coreRemindPlan.setState(0);
                coreRemindPlanMapper.insert(coreRemindPlan);
            }
        }*/

        this.sendMsgForOrder(coreWorkOrder.getId());
        return Response.ok();
    }

    public String getOrderNo() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String orderNo = sdf.format(new Date()) + (int) ((Math.random() * 9 + 1) * 1000);
        if (coreWorkOrderMapper.selectCount(new QueryWrapper<CoreWorkOrder>().eq("order_no", orderNo)) > 0) {
            this.getOrderNo();
        }
        return orderNo;
    }

    @Override
    public Response addForList(CoreWorkOrderListDto coreWorkOrderListDto) {
        for (CoreWorkOrder coreWorkOrder : coreWorkOrderListDto.getCoreWorkOrderList()) {
            coreWorkOrder.setCreateUserType(0);
            coreWorkOrder.setCreateTime(LocalDateTime.now());
            coreWorkOrder.setState(5);
            coreWorkOrder.setCreator(ShiroUtils.getUserId());
            coreWorkOrder.setAuditor(coreWorkOrder.getRepairId());
            coreWorkOrder.setEnterpriseId(iCoreProjectService.getById(coreWorkOrder.getProjectId()).getEnterpriseId());
            coreWorkOrder.setOrderNo(this.getOrderNo());
            coreWorkOrderMapper.insert(coreWorkOrder);
            //提醒计划暂时不需要
/*            if (!coreWorkOrderListDto.getRemindPlanType().equals(0)) {
                for (CoreRemindPlan coreRemindPlan : coreWorkOrderListDto.getCoreRemindPlanList()) {
                    coreRemindPlan.setWorkOrderId(coreWorkOrder.getId());
                    coreRemindPlan.setState(0);
                    coreRemindPlan.setSendTime(coreWorkOrder.getPlanTime());
                    coreRemindPlanMapper.insert(coreRemindPlan);
                }
            }*/
        }
        return Response.ok();
    }

    @Override
    public Response update(CoreWorkOrderDto coreWorkOrderDto) {
        CoreWorkOrder coreWorkOrder = new CoreWorkOrder();
        BeanUtils.copyProperties(coreWorkOrderDto, coreWorkOrder);
        coreWorkOrderMapper.updateByPrimaryKey(coreWorkOrder);
        if (coreWorkOrderDto.getSendMsg() != null && coreWorkOrderDto.getSendMsg().equals(1)) {
            this.sendMsgForOrder(coreWorkOrder.getId());
        }
        return Response.ok();
    }

    @Override
    public Response updateByWeiXin(CoreWorkOrder coreWorkOrder) {
        coreWorkOrderMapper.updateByWeiXin(coreWorkOrder);
        return Response.ok();
    }

    @Override
    public Response delOrderByWeiXin(Integer id) {
        CoreWorkOrder coreWorkOrder = coreWorkOrderMapper.selectById(id);
        if (!coreWorkOrder.getState().equals(0)) {
            return Response.error("非待审状态，无法删除");
        }
        if (!coreWorkOrder.getRepairId().equals(WeiXinUserUtils.getUserId())) {
            return Response.error("非发起人，无法删除");
        }
        coreWorkOrderMapper.deleteById(id);
        return Response.ok();
    }

    @Override
    public Response getList(Integer equipmentId, Integer sortType, String beginDate, String endDate, Integer warningDay, String projectName, String state, Integer disposeResult, Integer createUserType, String recipientName, Integer pageIndex, Integer pageSize) {
        IPage<CoreWorkOrderVo> coreWorkOrderVoIPage = coreWorkOrderMapper.getList(new Page(pageIndex, pageSize), equipmentId, sortType, beginDate, endDate, warningDay, projectName, state, disposeResult, createUserType, recipientName, ShiroUtils.getSeeAll().equals(1) ? null : ShiroUtils.getEnterpriseId());
        return Response.ok(coreWorkOrderVoIPage.getRecords(), coreWorkOrderVoIPage.getTotal());
    }

    @Override
    public Response getOne(Integer id) {
        return Response.ok(coreWorkOrderMapper.getOne(id));
    }

    @Override
    public Response getListForWeiXin(String state, Integer disposeResult, Integer pageIndex, Integer pageSize) {
        int sortType = 0;
        if (state != null && !state.contains("0") && !state.contains("1")) {
            sortType = 1;
        }
        IPage<CoreWorkOrderVo> coreWorkOrderVoIPage = coreWorkOrderMapper.getListForWeiXin(new Page(pageIndex, pageSize), WeiXinUserUtils.getUserId(), state, disposeResult, WeiXinUserUtils.getUserType(), sortType, WeiXinUserUtils.getEnterpriseId());
        return Response.ok(coreWorkOrderVoIPage.getRecords(), coreWorkOrderVoIPage.getTotal());
    }

    @Override
    public Response disposeOrder(CoreWorkOrder coreWorkOrder) {
        coreWorkOrder.setState(2);
        coreWorkOrder.setDisposeTime(LocalDateTime.now());
        coreWorkOrderMapper.disposeOrder(coreWorkOrder);
        return Response.ok();
    }

    @Override
    public Response getRemindList(LocalDate beginDate, LocalDate endDate, Integer type, Integer frequency) {
        //type: 1 year 2 month 3 week 4 day
        try {
            List remindList = RemindDateUtils.getRemindList(beginDate, endDate, type, frequency);
            return Response.ok(remindList);

        } catch (Exception e) {
            e.printStackTrace();
            return Response.error();
        }
    }

    @Override
    public Response updateRecipient(CoreWorkOrder coreWorkOrder) {
        //客户发起的工单不能修改报修人
        CoreWorkOrder coreWorkOrder1 = coreWorkOrderMapper.selectById(coreWorkOrder.getId());
        Integer repairId = coreWorkOrder1.getCreateUserType().equals(1) ? coreWorkOrder1.getRepairId() : coreWorkOrder.getRepairId();
        coreWorkOrderMapper.updateRecipient(coreWorkOrder.getFailureDescription(), coreWorkOrder.getRemark(), repairId, coreWorkOrder.getRecipient(), coreWorkOrder.getPlanTime(), 1, coreWorkOrder.getId());
        //发送短息和服务消息
        this.sendMsgForOrder(coreWorkOrder.getId());
        return Response.ok();
    }


    /**
     * 发发送短信和服务消息
     *
     * @param orderId
     */
    public void sendMsgForOrder(Integer orderId) {
        CoreWorkOrder coreWorkOrder = coreWorkOrderMapper.selectById(orderId);
        //维修人
        if (coreWorkOrder.getRecipient() != null) {
            this.sendSmsForEngineer(coreWorkOrder.getRecipient(), 0, coreWorkOrder.getOrderNo());
            this.sendWeappMessage(coreWorkOrder.getRecipient(), coreWorkOrder.getId(), 0);
        }
        //报修人
        if (coreWorkOrder.getRepairId() != null) {
            this.sendSmsForEngineer(coreWorkOrder.getRepairId(), 1, coreWorkOrder.getOrderNo());
            this.sendWeappMessage(coreWorkOrder.getRepairId(), coreWorkOrder.getId(), 1);
        }
    }

    @Override
    public Response updateOrderState(Integer state, Integer id) {
        coreWorkOrderMapper.updateOrderState(state, id);
        return Response.ok();
    }

    public void sendSmsForEngineer(Integer engineerId, Integer type, String orderNo) {
        SendSmsRequest req = new SendSmsRequest();
        CoreMaintenanceEngineer coreMaintenanceEngineer = coreMaintenanceEngineerMapper.selectById(engineerId);
        if (coreMaintenanceEngineer.getTel() != null) {
            // 需要发送短信的手机号码
            String[] phoneNumbers = {"86" + coreMaintenanceEngineer.getTel()};
            req.setPhoneNumberSet(phoneNumbers);

            String[] templateParamSet = {orderNo};
            req.setTemplateParamSet(templateParamSet);
            switch (type) {
                //处理人
                case 0:
                    req.setTemplateId("1401543");
                    break;
                //客户
                case 1:
                    req.setTemplateId("1401451");
                    break;
            }
            this.sendSms(req);
        }


    }

    public Response sendSms(SendSmsRequest req) {
        try {
            Credential cred = new Credential("AKIDQgyue8ZM5Xk4nq5OozvfIp67tPjntmY3", "NWQ5VerqZ1DAtMczC9pGSN2r9G7h1Aj9");
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setReqMethod("POST");
            httpProfile.setConnTimeout(60);
            httpProfile.setEndpoint("sms.tencentcloudapi.com");

            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setSignMethod("HmacSHA256");
            clientProfile.setHttpProfile(httpProfile);

            SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
            req.setSmsSdkAppId(TencentSmsConstant.APP_ID);
            req.setSignName("灵睿运维通");

            SendSmsResponse res = client.SendSms(req);
            return Response.ok("发送成功");
        } catch (Exception e) {
            return Response.error("发送失败");
        }
    }


    public void sendWeappMessage(Integer userId, Integer orderId, Integer type) {
        CoreWorkOrderVo coreWorkOrderVo = coreWorkOrderMapper.getOne(orderId);
        CoreUserBinding coreUserBinding = coreUserBindingMapper.selectOne(new QueryWrapper<CoreUserBinding>().eq("user_id", userId));
        if (coreWorkOrderVo != null && coreUserBinding != null) {
            String toUrl = "pages/workList/detail?id=";
            Map<String, Object> map;
            Map<String, Object> data = new HashMap<>();

            if (type == 0) {
                map = new HashMap<>();
                map.put("value", "新增工单处提醒");
                data.put("thing2", map);

                map = new HashMap<>();
                map.put("value", "您有新的工单，请及时处理。");
                data.put("thing1", map);

                map = new HashMap<>();
                map.put("value", coreWorkOrderVo.getRepairName());
                data.put("thing4", map);

                if (coreWorkOrderVo.getState().equals(1)) {
                    toUrl = "pages/workList/handle?id=";
                }
            } else if (type == 1) {
                map = new HashMap<>();
                map.put("value", "工单已指定处理人");
                data.put("thing2", map);

                map = new HashMap<>();
                map.put("value", "线上报修已受理，点击查看详情。");
                data.put("thing1", map);

                map = new HashMap<>();
                map.put("value", "灵睿运维通");
                data.put("thing4", map);
            }

            map = new HashMap<>();
            map.put("value", new SimpleDateFormat("yyyy-MM-dd").format(coreWorkOrderVo.getPlanTime()));
            data.put("time3", map);

            WxTemplateSend wxTemplateSend = new WxTemplateSend();
            wxTemplateSend.SendMessage("xrQAYpcPK8BkuLO2a4SOngD58enbJrhICJQ7s-x3X88", coreUserBinding.getOpenId(), this.getAccessToken(), data, toUrl, coreWorkOrderVo.getId());
        }

    }

    @Override
    public String getAccessToken() {
        String access_token = iRedisService.get("access_token");
        if (access_token == null || access_token.trim().equals("")) {
            access_token = WeiXinUtil.getAccessToken(WeiXinConfig.APP_ID, WeiXinConfig.APP_SECRET).getToken();
            iRedisService.set("access_token", access_token);
            iRedisService.expire("access_token", 6900);
        }
        return access_token;
    }

    @Override
    public Response auditOder(CoreWorkOrder coreWorkOrder) {
        CoreWorkOrder dbCoreWorkOrder = coreWorkOrderMapper.selectById(coreWorkOrder.getId());
        if (dbCoreWorkOrder == null || !dbCoreWorkOrder.getState().equals(2)) {
            return Response.error("工单状态异常，无法验收");
        }
        if (!dbCoreWorkOrder.getAuditor().equals(WeiXinUserUtils.getUserId())) {
            return Response.error("非验收人，无法验收");
        }
        coreWorkOrder.setAuditor(WeiXinUserUtils.getUserId());
        coreWorkOrder.setAuditTime(LocalDateTime.now());
        if (coreWorkOrderMapper.auditOder(coreWorkOrder) > 0) {
            return Response.ok();
        }
        return Response.error();
    }
}
